﻿// ----------------------------------------------------------------------------
// core_unit_test.cpp
// ----------------------------------------------------------------------------
#include <fw/base/core/macros.h>
#if defined(FW_ENABLE_UNIT_TEST)
#include <fw/base/core/debugconsole.h>
#include <gtest/gtest.h>
#include <fw/base/core/stdinteger.h>

using namespace fw;

// CORE/uint32_t内部関数の基本的なテスト. 
TEST(core, uint32)
{
	ASSERT_EQ(uint32_li  (1234),			1234);
	ASSERT_EQ(uint32_dec (1234),			1233);
	ASSERT_EQ(uint32_inc (1234),			1235);
	ASSERT_EQ(uint32_not (0x80000000),		0x7fffffff);
	ASSERT_EQ(uint32_neg (2),				0xfffffffe); // Two's complement.
	ASSERT_EQ(uint32_ext (1234),			0);
	ASSERT_EQ(uint32_ext (-123),			0xffffffff);
	ASSERT_EQ(uint32_and (0x77, 0x3c),		0x34);
	ASSERT_EQ(uint32_xor (0x10101010, 0xf0f0f0f0), 0xe0e0e0e0);
	ASSERT_EQ(uint32_xorl(0x10101010, 0xf0f0f0f0), 0);
	ASSERT_EQ(uint32_andc(0xff00ff00, 0x0000ffff), 0xff000000);
	ASSERT_EQ(uint32_or  (0xff00ff00, 0x0001ff00), 0xff01ff00);
	ASSERT_EQ(uint32_sll (0xff00ff00, 8),	0x00ff0000);
	ASSERT_EQ(uint32_srl (0xff00ff00, 8),	0x00ff00ff);
	ASSERT_EQ(uint32_sra (0x12345678, 8),	0x00123456);
	ASSERT_EQ(uint32_sra (0xff123456, 8),	0xffff1234);
	ASSERT_EQ(uint32_rol (0x12345678, 8),	0x34567812);
	ASSERT_EQ(uint32_ror (0x12345678, 8),	0x78123456);
	ASSERT_EQ(uint32_add (11, 3),			14);
	ASSERT_EQ(uint32_sub (11, 3),			8);
	ASSERT_EQ(uint32_mul (11, 3),			33);
	ASSERT_EQ(uint32_div (11, 3),			3);
	ASSERT_EQ(uint32_mod (11, 3),			2);
	ASSERT_EQ(uint32_cmpeq(12, 12),			0xffffffff);
	ASSERT_EQ(uint32_cmpeq(12, 10),			0);
	ASSERT_EQ(uint32_cmpneq(12, 10),		0xffffffff);
	ASSERT_EQ(uint32_cmpneq(12, 12),		0);
	ASSERT_EQ(uint32_cmplt(10, 12),			0xffffffff);
	ASSERT_EQ(uint32_cmplt(12, 12),			0);
	ASSERT_EQ(uint32_cmplt(13, 12),			0);
	ASSERT_EQ(uint32_cmple(10, 12),			0xffffffff);
	ASSERT_EQ(uint32_cmple(12, 12),			0xffffffff);
	ASSERT_EQ(uint32_cmple(13, 12),			0);
	ASSERT_EQ(uint32_cmpgt(12, 10),			0xffffffff);
	ASSERT_EQ(uint32_cmpgt(12, 12),			0);
	ASSERT_EQ(uint32_cmpgt(12, 14),			0);
	ASSERT_EQ(uint32_cmpge(12, 10),			0xffffffff);
	ASSERT_EQ(uint32_cmpge(12, 12),			0xffffffff);
	ASSERT_EQ(uint32_cmpge(12, 14),			0);
	ASSERT_EQ(uint32_setnz(15),				0xffffffff);
	ASSERT_EQ(uint32_setnz(0),				0);
	ASSERT_EQ(uint32_satadd(0x80000000, 0x80000001), 0xffffffff);
	ASSERT_EQ(uint32_satadd(0x00000008, 0x80000010), 0x80000018);
	ASSERT_EQ(uint32_satsub(0x80000008, 0x80000001), 7);
	ASSERT_EQ(uint32_satsub(0x00000008, 0x80000010), 0);
	ASSERT_EQ(uint32_satmul(4, 4),					 0x10);
	ASSERT_EQ(uint32_satmul(0xffff0000, 0x0000ffff), 0xffffffff);
	ASSERT_EQ(uint32_sels(0x80000000, 10, 20), 10);
	ASSERT_EQ(uint32_selb(0xf0f0f0f0, 0x11111111, 0x22222222), 0x12121212);
	ASSERT_EQ(uint32_imin(4, 5), 4);
	ASSERT_EQ(uint32_imin(-2, 3), -2);
	ASSERT_EQ(uint32_imax(4, 5), 5);
	ASSERT_EQ(uint32_imax(10, -1), 10);
	ASSERT_EQ(uint32_min(4, 5), 4);
	ASSERT_EQ(uint32_min(-2, 3), 3);
	ASSERT_EQ(uint32_max(4, 5), 5);
	ASSERT_EQ(uint32_max(10, -1), -1);
	ASSERT_EQ(uint32_incwrap(32, 0, 31), 33);
	ASSERT_EQ(uint32_incwrap(0, 2, 31), 1);
	ASSERT_EQ(uint32_incwrap(31, 0, 31), 0);
	ASSERT_EQ(uint32_decwrap(2, 5, 31), 1);
	ASSERT_EQ(uint32_decwrap(1, 0, 31), 0);
	ASSERT_EQ(uint32_decwrap(0, 0, 31), 31);
	ASSERT_EQ(uint32_cntbits_ref(0xffffffff), 32);
	ASSERT_EQ(uint32_cntbits_ref(0xf0f0f0f0), 16);
	ASSERT_EQ(uint32_cntbits_ref(0), 0);
	ASSERT_EQ(uint32_cntbits(0xffffffff), 32);
	ASSERT_EQ(uint32_cntbits(0xf0f0f0f0), 16);
	ASSERT_EQ(uint32_cntbits(0), 0);
	ASSERT_EQ(uint32_cntlz_ref(0x00000000), 32);
	ASSERT_EQ(uint32_cntlz_ref(0x0100f0f0), 7);
	ASSERT_EQ(uint32_cntlz_ref(0x80000000), 0);
	ASSERT_EQ(uint32_cntlz(0x00000000), 32);
	ASSERT_EQ(uint32_cntlz(0x0100f0f0), 7);
	ASSERT_EQ(uint32_cntlz(0x80000000), 0);
	ASSERT_EQ(uint32_shuffleA(0xffff), 0x55555555);
	ASSERT_EQ(uint32_shuffleB(0x03ff), 0x09249249);
	
}

// CORE/uint64_t内部関数の基本的なテスト.
TEST(core, uint64)
{
	ASSERT_EQ(uint64_li  (1234),			1234);
	ASSERT_EQ(uint64_dec (1234),			1233);
	ASSERT_EQ(uint64_inc (1234),			1235);
	ASSERT_EQ(uint64_not (0x0000000080000000ul),		0xffffffff7ffffffful);
	ASSERT_EQ(uint64_neg (2),				0xfffffffffffffffeul); // Two's complement.
	ASSERT_EQ(uint64_ext (1234),			0);
	ASSERT_EQ(uint64_ext (-123),			0xfffffffffffffffful);
	ASSERT_EQ(uint64_and (0x77, 0x3c),		0x34);
	ASSERT_EQ(uint64_xor (0x1010101010101010ul, 0xf0f0f0f0f0f0f0f0ul), 0xe0e0e0e0e0e0e0e0ul);
	ASSERT_EQ(uint64_xorl(0x1010101010101010ul, 0xf0f0f0f0f0f0f0f0ul), 0);
	ASSERT_EQ(uint64_xorl(0ul, 1ul), 1);
	ASSERT_EQ(uint64_andc(0xff00ff00ff00ff00ul, 0xffff00000000fffful), 0x0000ff00ff000000ul);
	ASSERT_EQ(uint64_or  (0x8fffffffff00ff00ul, 0x110011000001ff00ul), 0x9fffffffff01ff00ul);
	ASSERT_EQ(uint64_sll (0x1f00ff00ff00ff00ul, 8),	0x00ff00ff00ff0000ul);
	ASSERT_EQ(uint64_srl (0x1f00ff00ff00ff00ul, 8),	0x001f00ff00ff00fful);


}

#endif // FW_ENABLE_UNIT_TEST

void CORE_UNIT_TEST()
{
}
